package org.honeynet.hbbackend.maxmindgeoip;

import java.io.IOException;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.ConcurrencyManagementType;
import javax.ejb.EJBException;
import javax.ejb.Singleton;
import javax.ejb.Startup;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
import com.maxmind.geoip.LookupService;

@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class LookupServiceWrapper {
	
	private final static int CACHE_SIZE = 2000;
	
	private final ConcurrentLinkedHashMap<String, LocationWrapper> cache;
	private LookupService geoDb = null;
	
	@Resource(name="dbFile")
	String dbFile;
	
	Logger log = LoggerFactory.getLogger(LookupServiceWrapper.class);
	
	
	public LookupServiceWrapper() {
		cache = new ConcurrentLinkedHashMap.Builder<String, LocationWrapper>()
	    .maximumWeightedCapacity(CACHE_SIZE)
	    .concurrencyLevel(32) // mdb bean pool max
	    .build();
	}
	
	
	@PostConstruct
	private void init() {
		try {
			log.debug("instantiating LookupService dbFile = {}", dbFile);
			geoDb = new LookupService(dbFile, LookupService.GEOIP_STANDARD);
		} catch (IOException e) {
			log.error("got IOException while instantiating LookupService", e);
			geoDb.close();
			throw new EJBException(e);
		}
	}
	
	
	public LocationWrapper getLocation(String ip) {
		LocationWrapper lw = cache.get(ip);
		if (lw != null) {
			return lw;
		} else {
			lw = new LocationWrapper(geoDb.getLocation(ip));
			cache.put(ip, lw);
			return lw;
		}
	}

	
	//TODO
//	@PostConstruct
//	private void stop() {
//		if (geoDb != null) geoDb.close();
//	}
}
